package com.content.management.aop;

import com.alibaba.fastjson.JSON;
import com.content.management.util.HttpHelp;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;

/**
 * @author xinghu
 * @version 1.0
 * @date 2020/2/10 3:40 下午
 */
@Slf4j
@Component
@Aspect
public class RequestLog {

	@Pointcut(
			value = "execution(public * com.content.management.controller.web.*.*(..))")
	public void operationLog() {
	}

	@Around(value = "operationLog()")
	public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {

		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		assert attributes != null;
		HttpServletRequest request = attributes.getRequest();
		log.info("REQUEST>>>>>>>>>>{}", request.getRequestURL().toString());
		log.info("HTTP_METHOD {}", request.getMethod());
		log.info("IP {}", HttpHelp.getIPAddress(request));
		log.info("CLASS_METHOD {}", joinPoint.getSignature().getDeclaringTypeName());
		Object[] args = joinPoint.getArgs();
		List<Object> list = Lists.newArrayList();
		for (Object arg : args) {
			if (arg instanceof ServletRequest || arg instanceof ServletResponse) {
				continue;
			} else if (arg instanceof MultipartFile) {
				list.add(((MultipartFile) arg).getOriginalFilename());
				continue;
			}
			list.add(arg);
		}
		String argsStr = JSON.toJSONString(list);
		log.info("ARGS {}", argsStr);
		Object result = null;
		try {
			result = joinPoint.proceed();
		} finally {
			log.info("RESPONSE<<<<<<<<<<{}", Objects.nonNull(result) ? JSON.toJSONString(result) : "null");
		}
		return result;
	}
}